/******************************************************
 * @file mouse.c
 * @author Destiny 
 * @brief 鼠标设备相关函数
 * 
 * @version 0.1
 * @date 2024-07-18
 *****************************************************/
#include <config.h>
#include <input_manager.h>
#include <disp_manager.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/input.h>

static int g_iFd;  /*鼠标设备节点文件描述符*/
/*
 * @description		    	: 鼠标设备初始化函数
 * @param - 				: 无
 * @return 			    	: 0 成功;其他 失败
 */
static int MouseDevInit(void)
{
    g_iFd = open(MOUSE_DEVICE_PATH, O_RDONLY);
    if (g_iFd < 0)
    {
        DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG,"can't open  %s\r\n", MOUSE_DEVICE_PATH);
        return -1;
    }
    return 0;
}

/*
 * @description		    	: 鼠标设备注销函数
 * @param - 				: 无
 * @return 			    	: 0 成功;其他 失败
 */
static int MouseDevExit(void)
{
    close(g_iFd);
    return 0;
}
/*struct input_event {
	struct timeval time;
	__u16 type;
	__u16 code;
	__s32 value;
};
*/
/*
 * @description		    	: 鼠标设备输入事件获取函数
 * @param - ptInputEvent	: 输入数据描述结构体指针
 * @return 			    	: 0 成功;其他 失败
 */
static int MouseGetInputEvent(PT_InputEvent ptInputEvent)
{
    struct input_event tTemp;
    int iRet;
    int iXres, iYres, iBpp;
    int iWheelFlag = 0;
    fd_set readfds;
    GetDispResolution(&iXres, &iYres, &iBpp);
    while (1)
    {
        FD_ZERO(&readfds);   /*清空readfds集合*/
        FD_SET(g_iFd, &readfds);  /*向readfds集合中添加鼠标设备节点描述符*/
        iRet = select(g_iFd + 1, &readfds, NULL, NULL, NULL);   /*设置轮询*/
        if (iRet == 1)
        {
            if(FD_ISSET(g_iFd,&readfds))
            {
                read(g_iFd, &tTemp,sizeof(struct input_event));
                switch (tTemp.type)
                {
                    case EV_KEY:   /*鼠标点击*/
                    {
                        switch (tTemp.code)
                        {
                            case BTN_LEFT:
                            case BTN_RIGHT:  /*左键或右键点击*/
                            {
                                ptInputEvent->iPressure = tTemp.value;
                                break;
                            }   
                            case BTN_MIDDLE:
                                break;
                            default:
                                break;
                        }
                        break;
                    }
                    case EV_REL:  /*鼠标移动，相对位移*/
                    {
                        switch (tTemp.code)
                        {
                            case REL_X:
                            {
                                ptInputEvent->iX += tTemp.value;
                                break;
                            }
                            case REL_Y:
                            {
                                ptInputEvent->iY += tTemp.value;
                                break;
                            }
                            case REL_WHEEL:   /*鼠标滚轮*/
                                iWheelFlag = 1;
                                ptInputEvent->iWheel = tTemp.value;
                                break;
                            default:
                                break;
                        }
                        break;
                    }
                    case EV_SYN:  /*同步事件返回*/
                        ptInputEvent->iX = (ptInputEvent->iX < 0)? 0 :((ptInputEvent->iX > iXres)? iXres : ptInputEvent->iX);
                        ptInputEvent->iY = (ptInputEvent->iY < 0)? 0 :((ptInputEvent->iY > iYres)? iYres : ptInputEvent->iY);
                        ptInputEvent->iWheel = iWheelFlag ? ptInputEvent->iWheel : 0;
                        ptInputEvent->tTime = tTemp.time;
                        ptInputEvent->iInputDevice = INPUT_DEVICE_MOUSE;
                        return 0;
                }
            }
        }
        else
        {
            return -1;
        }
    }
    return 0;
}
/*鼠标设备结构体*/
static T_InputOpr g_tMouseOpr = {
    .name = "Mouse",
    .DeviceInit = MouseDevInit,
    .DeviceExit = MouseDevExit,
    .GetInputEvent = MouseGetInputEvent,
};

int MouseInit(void)
{
    return RegisterInputOpr(&g_tMouseOpr);
}
